-module(server_reader).

-include("common.hrl").

-define(TCP_TIMEOUT, 60*1000). % 解析协议超时时间
-define(HEART_TIMEOUT, 60*1000). % 心跳包超时时间
-define(HEART_TIMEOUT_TIME, 1).  % 心跳包超时次数
-define(HEADER_LENGTH, 5). % 消息头长度

%%记录客户端进程
-record(client, {
%% 			t_users,
            user_pid = undefined,
			user_id = 0,
            login  = 0,
            site  = undefined,
            user_name = undefined,
            timeout = 0 % 超时次数
     }).

-export([start_link/0, init/0]).

start_link() ->
    {ok, proc_lib:spawn_link(?MODULE, init, [])}.

%%初始化
init() ->
    process_flag(trap_exit, true),
    Client = #client{
                user_pid = undefined,
                login  = 0,
                user_id  = 0,
				site = undefined,
                user_name = undefined,
                timeout = 0 
            },
    receive
        {go, Socket} ->
			try
				?INFO_MSG("init ok", []),
				ets:insert(ets_socket, {Socket}), %% TODO 测试
            	get_socket_data(Socket, Client)
			catch 
				_:Reason ->
%% 				  login_lost(Socket, Client, 11, {error, Reason}),
				  ?WARNING_MSG("get_socket_data:~w",[Reason]),
				  ?WARNING_MSG("get_stacktrace:~p",[erlang:get_stacktrace()]),
				  error
			end
    end.

get_socket_data(Socket, Client) ->
	Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT),
	receive
		{inet_async, Socket, Ref, {ok, <<Len:16, _IsZip:8, Cmd:16>>}} ->
			login_parse_packet(Socket, Client, Cmd, Len);
		_Other -> 
			%% TODO 测试  删除socket
			ets:delete_object(ets_socket, {Socket}),
			gen_tcp:close(Socket)
	end.

login_parse_packet(Socket, Client, _Cmd, Len) ->
	BodyLen = Len - ?HEADER_LENGTH,
	case BodyLen > 0 of
		true -> 
			Ref = async_recv(Socket, BodyLen, ?TCP_TIMEOUT),
			receive
				{inet_async, Socket, Ref, {ok, Binary}} ->
					?INFO_MSG("receive ~p", [Binary]),
					%gen_tcp:send(Socket, Binary),
					%% TODO 测试
					Sockets = ets:tab2list(ets_socket),
					[gen_tcp:send(NewSocket, Binary) || {NewSocket} <- Sockets],
					%%
					get_socket_data(Socket, Client);
				Other ->
					?INFO_MSG("receive ~p", [Other]),
					gen_tcp:close(Socket)
			end
	end.
			

%% 接受信息
async_recv(Sock, Length, Timeout) when is_port(Sock) ->
    case prim_inet:async_recv(Sock, Length, Timeout) of
        {error, Reason} -> 	
			throw({Reason});
        {ok, Res}       ->  
			Res;
        Res             ->	
			Res
    end.
	
